﻿using System;
using System.Text;
using System.Threading.Tasks;

using Microsoft.AspNetCore.Http;
using Microsoft.Net.Http.Headers;

using Newtonsoft.Json;
  
using MingYuanYun.StructuredLog.Abstractions;
using MingYuanyun.WebApi.Abstractions;

namespace MingYuanYun.WebApi.Logging
{
    public class ErrorHandlingMiddleware
    {
        private static readonly string JsonContentType =
            new MediaTypeHeaderValue("application/json") { Encoding = Encoding.UTF8 }.ToString();

        private readonly RequestDelegate _next;

        public ErrorHandlingMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        // If a middleware components takes in constructor arguments they must be singleton-lifetime
        // If a middleware components takes in Invoke method arguments they can be singleton-lifetime or scoped-lifetime
        public async Task Invoke(HttpContext context, IMyLogger logger)
        {
            try
            {
                await _next(context);
            }
            catch (MingYuanYun.Exception.BusinessException bex)
            {
                logger.Error(bex);
                context.Response.StatusCode = StatusCodes.Status200OK;
                context.Response.ContentType = JsonContentType;
                var errorResult = new HttpRequestResult(null, false, bex.Message);
                await context.Response.WriteAsync(JsonConvert.SerializeObject(errorResult));
            }
            catch (System.Exception ex)
            {
                logger.Error(ex);

                // context.Response.StatusCode = StatusCodes.Status500InternalServerError;
                context.Response.StatusCode = StatusCodes.Status500InternalServerError;
                context.Response.ContentType = JsonContentType;
                //#if DEBUG
                //				var errorResult = new HttpRequestResult(null, true, ex.ToString());
                //#else
                //				var errorResult = new HttpRequestResult(null, true, ex.Message);
                //#endif
                var errorResult = new HttpRequestResult(null, false, ex.Message);

                await context.Response.WriteAsync(JsonConvert.SerializeObject(errorResult));
            }
        }
    }
}
